﻿// This file is part of VideoLan.Inteop
//
// Copyright (C) 2008, Michael Melendez, http://www.MeediOS.com
//
//VideoLan.Inteop is free software; you can redistribute it and/or
//modify it under the terms of the GNU Lesser General Public
//License as published by the Free Software Foundation; either 
//version 2.1 of the License, or (at your option) any later version.
//
//VideoLan.Inteop is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public 
//License along with this library.  If not, see <http://www.gnu.org/licenses/>.


using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;

namespace VideoLan
{
    public class VideoLanClient : IDisposable
    {
        #region Private Members

        /// <summary>
        /// COM pointer to a vlc exception.  We will only use 1 exception pointer, 
        /// so we must always clear it out after use
        /// </summary>
        private libvlc_exception_t p_exception;

        /// <summary>
        /// COM pointer to our vlc instance
        /// </summary>
        internal IntPtr p_instance;

        internal string RootPath;
        internal string PluginPath;

        #endregion

        public VideoLanClient()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory;

            //string[] args = {path,
            //    "--no-one-instance",
            //    "--no-loop",
            //    "--no-drop-late-frames",
            //    //":disable-screensaver",
            //    //":vout=direct3d",
            //    //"--plugin-path=" + Path.Combine(path,"plugins")
            //};
            Initalize(path, MulticastTV.Globals.vlcargs); 
        }

        public VideoLanClient(string VlcDirectory)
        {
            //string[] args = {VlcDirectory,
            //    "--no-one-instance",
            //    "--no-loop",
            //    "--no-drop-late-frames",
            //    //":disable-screensaver",
            //    //":vout=direct3d",
            //    //"--plugin-path=" + Path.Combine(VlcDirectory,"plugins")
            //};
            Initalize(VlcDirectory, MulticastTV.Globals.vlcargs);
        }
        
        public VideoLanClient(string VlcDirectory, string[] args)
        {
            Initalize(VlcDirectory, args);
        }
        ~VideoLanClient()
        {
            Dispose(false);
        }


        #region IDisposable Methods
        
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        
        protected void Dispose(bool disposing)
        {
            // release managed code
            if (disposing)  
            {

            }
            if (p_instance != IntPtr.Zero)
            {
                InteropMethods.libvlc_release(p_instance);
            }
            p_instance = IntPtr.Zero;
        }

        #endregion
        private void Initalize(string VlcDirectory, string[] args)
        {
            RootPath = VlcDirectory;

            //save the original EnviornmentDirectory.
            string originalDir = Environment.CurrentDirectory;
            //Set the directory to load the COM object libvlc.dll
            Environment.CurrentDirectory = VlcDirectory;

            //Initalize our exception pointer
            p_exception = new libvlc_exception_t();
            p_exception.Initalize();
            //create out vlc instance
            this.p_instance = InteropMethods.libvlc_new(args.Length, args, ref p_exception);
            p_exception.CheckException();

            //restore the original EnviornmentDirectory.
            Environment.CurrentDirectory = originalDir;
        }

        public VlcMedia NewMedia(byte[] MRL)
        {
            IntPtr p_media = InteropMethods.libvlc_media_new(p_instance, MRL, ref p_exception);
            p_exception.CheckException();
            return new VlcMedia(p_media);
        }
        public VlcMediaList NewMediaList()
        {
            IntPtr p_mlist = InteropMethods.libvlc_media_list_new(p_instance, ref p_exception);
            p_exception.CheckException();
            return new VlcMediaList(this, p_mlist);
        }
        public VlcMediaPlayer NewMediaPlayer(IntPtr parent)
        {
            IntPtr p_media_player = InteropMethods.libvlc_media_player_new(p_instance, ref p_exception);
            p_exception.CheckException();
            InteropMethods.libvlc_media_player_set_hwnd(p_media_player, parent, ref p_exception);
            p_exception.CheckException();
            return new VlcMediaPlayer(this, p_media_player);
        }
        public VlcMediaPlayer NewMediaPlayer(IntPtr parent, VlcMedia media)
        {
            IntPtr p_media_player = InteropMethods.libvlc_media_player_new_from_media(media.p_media,  ref p_exception);
            p_exception.CheckException();
            InteropMethods.libvlc_media_player_set_hwnd(p_media_player, parent, ref p_exception);
            p_exception.CheckException();
            return new VlcMediaPlayer(this, p_media_player);
        }
        public VlcMediaListPlayer NewMediaListPlayer(IntPtr parent)
        {
            return NewMediaListPlayer(parent, this.NewMediaList());
        }
        public VlcMediaListPlayer NewMediaListPlayer(IntPtr parent, VlcMediaList playlist)
        {
            IntPtr p_media_player = InteropMethods.libvlc_media_player_new(p_instance, ref p_exception);
            p_exception.CheckException();
            InteropMethods.libvlc_media_player_set_hwnd(p_media_player, parent, ref p_exception);
            p_exception.CheckException();
            IntPtr p_ml_player = InteropMethods.libvlc_media_list_player_new(p_instance, ref p_exception);
            p_exception.CheckException();
            return new VlcMediaListPlayer(this,playlist, p_ml_player, p_media_player);
        }
    }
}
